#include<iostream>
#include<vector>
using namespace std;
/*
有一堆石头，用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。
每一回合，从中选出任意两块石头，然后将它们一起粉碎。假设石头的重量分别为 x 和 y，且 x <= y。那么粉碎的可能结果如下：
如果 x == y，那么两块石头都会被完全粉碎；
如果 x != y，那么重量为 x 的石头将会完全粉碎，而重量为 y 的石头新重量为 y-x。
最后，最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下，就返回 0。

解题思路：改题目可以转化为求给定数组里面分成最相近两个子集之和，
求出target=sum/2,求能够尽量填满target容量背包的最大重量
这样就转化成了求0-1背包问题
dp[j]表示背包容量为j时所能装下的最大重量
递推公式为：dp[j] = max(dp[j],dp[j-stones[i]]+stones[i])
*/
int max(int a,int b)
{
    if(a>b)
        return a;
    else
        return b;
}
int dp(vector<int> stones)
{
    //初值条件的判断
    if(stones.size()<2)
        return stones[0];
    int sum=0;
    for(int i=0;i<stones.size();i++)
        sum+=stones[i];
    int target = sum>>1;
    //dp数组初始化
    vector<int> dp(target+1);
    dp[0] = 0;
    //遍历dp数组
    for(int i=0;i<stones.size();i++)
    {
        for(int j=target;j>=stones[i];j--)
        {
            dp[j] = max(dp[j],dp[j-stones[i]]+stones[i]);
            cout<<dp[j]<<" ";
        }
        cout<<endl;
    }
    int result = sum-2*dp[target];
    return result;
}

int main()
{
    cout<<"enter a number:"<<endl;
    int number;
    cin>>number;
    cout<<"enter nums:"<<endl;
    vector<int> stones(number);
    for(int i=0;i<number;i++)
        cin>>stones[i];
    cout<<dp(stones);
    return 0;
}